package com.tax.infrastructure.extension;

import com.tax.config.exception.BusinessException;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;

@Component
public class ExtensionRegister {

    @Autowired
    private ExtensionRepository extensionRepository;

    public void doRegistration(ExtensionPointI targetClz) {
        Class<?> extensionClass = targetClz.getClass();
        Extension annotation = AnnotationUtils.findAnnotation(extensionClass, Extension.class);
        String extClassName = calculateExtensionPoint(extensionClass);
        BizScenario bizScenario = BizScenario.valueOf(annotation.bizId(), annotation.useCase(), annotation.scenario());
        ExtensionCoordinate extensionCoordinate=new ExtensionCoordinate(extClassName,bizScenario.getUniqueIdentity());
        extensionRepository.put(extensionCoordinate,targetClz);
    }

    private String calculateExtensionPoint(Class<?> targetClz) {
        Class<?>[] interfaces = ClassUtils.getAllInterfacesForClass(targetClz);
        if (ArrayUtils.isEmpty(interfaces)) {
            throw new BusinessException("Please assign a extension point interface for " + targetClz);
        }
        for (Class inf : interfaces) {
            if (ExtensionPointI.class.isAssignableFrom(inf)){
                return inf.getName();
            }
        }
        throw new BusinessException("Please must implements 'ExtensionPointI' interface, " + targetClz);
    }
}
